#include "./WizAccessorBuffer.hpp"

namespace Wiz
{
    namespace Accessor
    {
        namespace Buffer
        {
            ::Wiz::Bool::Type   Type::Read(::Wiz::Byte::OutPtr BuffPtr, ::Wiz::Size::In ReadSize)
            {
                ::Wiz::Memory::Copy(BuffPtr, m_BufferPtr->GetPtr() + m_CurrPos, ReadSize);
                return ::Wiz::Bool::True;
            }
            ::Wiz::Bool::Type   Type::Write(::Wiz::Byte::InPtr DataPtr, ::Wiz::Size::In WriteSize)
            {
                ::Wiz::USize32::Type LastPos = m_CurrPos + WriteSize;
                if (LastPos > m_BufferPtr->CalcMaxElementCount())
                {
                    if (m_BufferPtr->Expand(WriteSize) == ::Wiz::Bool::False)
                    {
                        return ::Wiz::Bool::False;
                    }
                }
                ::Wiz::Memory::Copy(m_BufferPtr->GetPtr() + m_CurrPos, DataPtr, WriteSize);
                if (LastPos > m_BufferPtr->m_ElementCount)
                {
                    m_BufferPtr->m_ElementCount = LastPos;
                }
                return ::Wiz::Bool::True;
            }

            ::Wiz::Bool::Type   Type::ReadAndAdvance(::Wiz::Byte::OutPtr BuffPtr, ::Wiz::Size::In ReadSize)
            {
                if (this->Read(BuffPtr, ReadSize))
                {
                    this->Move(ReadSize);
                    return ::Wiz::Bool::True;
                }
                return ::Wiz::Bool::False;
            }
            ::Wiz::Bool::Type   Type::WriteAndAdvance(::Wiz::Byte::InPtr DataPtr, ::Wiz::Size::In WriteSize)
            {
                if (this->Write(DataPtr, WriteSize))
                {
                    this->Move(WriteSize);
                    return ::Wiz::Bool::True;
                }
                return ::Wiz::Bool::False;
            }

            ::Wiz::USize32::Type  Type::CurrentPosition()
            {
                return m_CurrPos;
            }
            ::Wiz::Void::Type   Type::MoveTo(::Wiz::USize32::In Pos)
            {
                WIZ_ASSERT(Pos <= m_BufferPtr->CalcMaxElementCount());
                m_CurrPos = Pos;
            }
            ::Wiz::Void::Type   Type::MoveToBegin()
            {
                m_CurrPos = 0;
            }
            ::Wiz::Void::Type   Type::MoveToEnd()
            {
                m_CurrPos = m_BufferPtr->CalcMaxElementCount();
            }
            ::Wiz::Void::Type   Type::Move(::Wiz::USize32::In InOffset)
            {
                WIZ_ASSERT((m_CurrPos + InOffset) <= m_BufferPtr->CalcMaxElementCount());
                m_CurrPos += InOffset;
            }

            ::Wiz::Bool::Type Type::Expand(::Wiz::USize32::In ESz)
            {
                return m_BufferPtr->Expand(m_BufferPtr->Size() + ESz);
            }
            ::Wiz::Bool::Type Type::Expand(::Wiz::Byte::Ptr DataPtr, ::Wiz::USize32::In ESz)
            {
                if (m_BufferPtr->Resize(m_BufferPtr->Size() + ESz) == ::Wiz::Bool::False)
                {
                    return ::Wiz::Bool::False;
                }
                ::Wiz::Memory::Copy(m_BufferPtr->GetPtr() + m_BufferPtr->m_ElementCount, DataPtr, ESz);
                m_BufferPtr->m_ElementCount += ESz;
                return ::Wiz::Bool::True;
            }
        } /// end of namespace Buffer
    } /// end of namespace Accessor
} /// end of namespace Wiz
